package com.manager.container.controller;

import com.manager.common.annotation.NestingModel;
import com.manager.common.constant.TcpDataType;
import com.manager.common.customer.utils.RemoteApi;
import com.manager.common.customer.utils.RemoteExecute;
import com.manager.common.job.IntervalBackupContainerVolume;
import com.manager.common.quartz.QuartzManager;
import com.manager.common.quartz.impl.CornJonEntity;
import com.manager.common.utils.DataTools;
import com.manager.common.utils.ObjectUtils;
import com.manager.common.vo.PageVO;
import com.manager.common.vo.ResultVO;
import com.manager.container.service.DockerDeployService;
import com.manager.model.*;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping("/deploy")
public class DockerDeployController {

    @Autowired
    private DockerDeployService dockerDeployService;

    @RequestMapping("/getDeployPage")
    public PageVO getDeployPage(DockerDeploy model) {
        try{
            return dockerDeployService.getDeployPage(model);
        }catch (Exception e){
            e.printStackTrace();
        }
        return PageVO.create(0,0,null);
    }

    @RequestMapping("/getRealContainerInfo")
    public PageVO getRealContainerInfo(DockerDeploy model) {
        try{
            return dockerDeployService.getRealContainerInfo(model);
        }catch (Exception e){
            e.printStackTrace();
        }
        return PageVO.create(0,0,null);
    }
    /**
     * {field: "containerName", "desc": "容器名称"},
     *   {field: "realTimeCpu", "desc": "cpu%"},
     *   {field: "realTimeMemory", "desc": "内存%"},
     *   {field: "realTimeNetwork", "desc": "网络"},
     *   {field: "ports", "desc": "端口"},
     *   {field: "runState", "desc": "运行状态", dicType: "run_state"}
     * */
    @RequestMapping("/getContainersStat")
    public ResultVO getContainersStat(DockerDeploy model){
        try{
            String url = DataTools.getSystemSettingStringValByKey("get_container_real_time_info_url");
            ResultVO<JSONArray> resultVO = RemoteApi.executeHttp(url);
            return resultVO;
        }catch (Exception e){
            e.printStackTrace();
        }
        return ResultVO.failed();
    }

    @RequestMapping("/addOrUpdate")
    public ResultVO addOrUpdate(DockerDeploy model) {
        try{
            if(StringUtils.isEmpty(model.getId())){
                dockerDeployService.addDeploy(model);
            }else {
                dockerDeployService.updateDeploy(model);
            }
            return ResultVO.success();
        }catch (Exception e){
            e.printStackTrace();
        }
        return ResultVO.failed();
    }

    @RequestMapping("/delete")
    public ResultVO delete(@NestingModel DockerDeploy model) {
        try{
            DockerDeploy dockerDeploy = dockerDeployService.getDockerDeployById(model);
            String command1 = " docker stop  " + dockerDeploy.getContainerID();
            String command2 = " docker rm " + dockerDeploy.getContainerID();
            ResultVO resultVO = RemoteExecute.executeSsh(command1,command2);
            if(resultVO.getCode() != 1){
                return ResultVO.failed("远程删除容器失败!");
            }
            dockerDeployService.deleteDeploy(model);
            return ResultVO.success();
        }catch (Exception e){
            e.printStackTrace();
        }
        return ResultVO.failed();
    }

    @RequestMapping("/getNoDeployedContainerList")
    public ResultVO getNoDeployedContainerList(DockerDeploy model) {
        try {
            List<DockerDeploy> list = dockerDeployService.getNoDeployedContainerList();
            return ResultVO.success(ObjectUtils.getJSONArray(DockerDeploy.config,list));
        }catch (Exception e){
            e.printStackTrace();
        }
        return ResultVO.failed();
    }

    @RequestMapping("/getDeployedContainerList")
    public ResultVO getDeployedContainerList(DockerDeploy model) {
        try {
            List<DockerDeploy> list = dockerDeployService.getDeployedContainerList();
            return ResultVO.success(ObjectUtils.getJSONArray(DockerDeploy.config,list));
        }catch (Exception e){
            e.printStackTrace();
        }
        return ResultVO.failed();
    }

    @RequestMapping("/updateBaseInfo")
    public ResultVO updateBaseInfo(@NestingModel DockerDeploy model) {
        try{
            dockerDeployService.updateBaseInfo(model);
            return ResultVO.success();
        }catch (Exception e){
            e.printStackTrace();
        }
        return ResultVO.failed();
    }

    @RequestMapping("/updateResourceInfo")
    public ResultVO updateResourceInfo(DockerDeploy model) {
        try{
            dockerDeployService.updateResourceInfo(model);
            return ResultVO.success();
        }catch (Exception e){
            e.printStackTrace();
        }
        return ResultVO.failed();
    }

    @RequestMapping("/updateDockerEnvFilePath")
    public ResultVO updateDockerEnvFilePath(DockerDeploy model) {
        try{
            dockerDeployService.updateDockerEnvFilePath(model);
            return ResultVO.success();
        }catch (Exception e){
            e.printStackTrace();
        }
        return ResultVO.failed();
    }

    @RequestMapping("/updateParamsFilePath")
    public ResultVO updateParamsFilePath(DockerDeploy model) {
        try{
            dockerDeployService.updateParamsFilePath(model);
            return ResultVO.success();
        }catch (Exception e){
            e.printStackTrace();
        }
        return ResultVO.failed();
    }

    @RequestMapping("/updateCustomParams")
    public ResultVO updateCustomParams(DockerDeploy model) {
        try{
            dockerDeployService.updateCustomParams(model);
            return ResultVO.success();
        }catch (Exception e){
            e.printStackTrace();
        }
        return ResultVO.failed();
    }

    @RequestMapping("/updateVolumes")
    public ResultVO updateVolumes(@NestingModel DockerDeploy model) {
        try{
            dockerDeployService.updateVolumes(model);
            return ResultVO.success();
        }catch (Exception e){
            e.printStackTrace();
        }
        return ResultVO.failed();
    }

    @RequestMapping("/updateNetwork")
    public ResultVO updateNetwork(@NestingModel DockerDeploy model) {
        try{
            dockerDeployService.updateNetwork(model);
            return ResultVO.success();
        }catch (Exception e){
            e.printStackTrace();
        }
        return ResultVO.failed();
    }

    @RequestMapping("/deploy")
    public ResultVO deploy(@NestingModel  DockerDeploy model){
        try{
            DockerDeploy dockerDeploy = dockerDeployService.getDockerDeployById(model);
            DockerImages dockerImages = dockerDeploy.getDockerImages();
            if(dockerImages == null || StringUtils.isEmpty(dockerImages.getImageId())){
                return ResultVO.failed("请检查镜像是否已经推送到服务器!");
            }
            StringBuffer stringBuffer = new StringBuffer();
            stringBuffer.append("docker run -it -d --restart=always ").append(" --name ").append(dockerDeploy.getContainerName());

            if(StringUtils.isNotEmpty(dockerDeploy.getNetworkIp())){
                stringBuffer.append(" --ip ").append(dockerDeploy.getNetworkIp());
            }
            if(dockerDeploy.getCpu() != null){
                stringBuffer.append(" --cpus=").append("\"").append(dockerDeploy.getCpu().intValue()).append("\"");
            }
            if(dockerDeploy.getMemory() != null){
                stringBuffer.append(" --memory=").append("\"").append(dockerDeploy.getMemory().intValue()).append("m").append("\"");
            }
            if(dockerDeploy.getDisk() != null){
                stringBuffer.append(" --storage-opt size=").append(dockerDeploy.getDisk().intValue()).append("G");
            }
            List<DockerDeployNetwork> dockerDeployNetworkList = dockerDeploy.getDockerDeployNetworkList();
            for(DockerDeployNetwork dockerDeployNetwork : dockerDeployNetworkList){
                stringBuffer.append(" -p ").append(dockerDeployNetwork.getHostPort()).append(":").append(dockerDeployNetwork.getContainerPort());
            }
            List<DockerDeployVolume> dockerDeployVolumeList = dockerDeploy.getDockerDeployVolumeList();
            for(DockerDeployVolume dockerDeployVolume : dockerDeployVolumeList){
                stringBuffer.append(" -v ").append(dockerDeployVolume.getHostPath()).append(":").append(dockerDeployVolume.getContainerPath());
            }
            stringBuffer.append(" --privileged=true ");
            stringBuffer.append(dockerImages.getName()).append(":").append(dockerImages.getTag());
            System.out.println(stringBuffer.toString());
            //ee8bed83c898
            ResultVO<Object[]> resultVO = RemoteExecute.executeSsh(stringBuffer.toString());
            if(resultVO.getCode() != 1){
                dockerDeploy.setDeployState(-1);
                dockerDeployService.updateContainerDeployInfo(dockerDeploy);
                return ResultVO.failed();
            }
            String containerId = ((String) resultVO.getData()[0]).substring(0,12);
            dockerDeploy.setContainerID(containerId);
            dockerDeploy.setDeployState(1);
            //查询容器运行状态
            String searchCommand = "docker inspect   "+containerId+" | grep 'Status' | cut -d ':' -f 2 | sed 's/\"//g' | sed 's/,//g'";
            System.out.println(searchCommand);
            ResultVO<Object[]> runningVO = RemoteExecute.executeSsh(searchCommand);
            if(runningVO.getData().length > 0){
                String msg = runningVO.getData()[0].toString();
                dockerDeploy.setRunState(msg);
            }
            dockerDeployService.updateContainerDeployInfo(dockerDeploy);
            return ResultVO.success();
        }catch (Exception e){
            e.printStackTrace();
        }
        return ResultVO.failed();
    }

    @RequestMapping("/start")
    public ResultVO start(@NestingModel DockerDeploy model){
        try{
            DockerDeploy dockerDeploy = dockerDeployService.getDockerDeployById(model);
            String command = "docker start " + dockerDeploy.getContainerID() ;
            ResultVO resultVO = RemoteExecute.executeSsh(command);
            //查询容器运行状态
            String searchCommand = "docker inspect   "+dockerDeploy.getContainerID()+" | grep 'Status' | cut -d ':' -f 2 | sed 's/\"//g' | sed 's/,//g'";
            System.out.println(searchCommand);
            ResultVO<Object[]> runningVO = RemoteExecute.executeSsh(searchCommand);
            if(runningVO.getData().length > 0){
                String msg = runningVO.getData()[0].toString();
                dockerDeploy.setRunState(msg);
            }
            dockerDeployService.updateContainerDeployInfo(dockerDeploy);
            return ResultVO.success();
        }catch (Exception e){
            e.printStackTrace();
        }
        return ResultVO.failed();
    }

    @RequestMapping("/stop")
    public ResultVO stop(@NestingModel  DockerDeploy model){
        try{
            DockerDeploy dockerDeploy = dockerDeployService.getDockerDeployById(model);
            String command = "docker stop " + dockerDeploy.getContainerID() ;
            ResultVO resultVO = RemoteExecute.executeSsh(command);
            String searchCommand = "docker inspect   "+dockerDeploy.getContainerID()+" | grep 'Status' | cut -d ':' -f 2 | sed 's/\"//g' | sed 's/,//g'";
            System.out.println(searchCommand);
            ResultVO<Object[]> runningVO = RemoteExecute.executeSsh(searchCommand);
            if(runningVO.getData().length > 0){
                String msg = runningVO.getData()[0].toString();
                dockerDeploy.setRunState(msg);
            }
            dockerDeployService.updateContainerDeployInfo(dockerDeploy);
            return ResultVO.success();
        }catch (Exception e){
            e.printStackTrace();
        }
        return ResultVO.failed();
    }

    @RequestMapping("/updateContainerBackupCorn")
    public ResultVO updateContainerBackupCorn(@NestingModel DockerDeploy model){
        try{
            dockerDeployService.updateContainerBackupCorn(model);
            DockerDeploy dockerDeploy = dockerDeployService.getDockerDeployById(model);
            if(QuartzManager.getInstance().isJobExist(dockerDeploy.getId())){
                if(dockerDeploy.getHasEnableBackup() == 1){
                    QuartzManager.getInstance().updateCornJobDate(dockerDeploy.getId(),dockerDeploy.getScheduledCorn());
                }else {
                    QuartzManager.getInstance().deleteJob(dockerDeploy.getId());
                }
            }else if(dockerDeploy.getHasEnableBackup() == 1){
                String aliseName = "备份容器挂载数据" + "【"+dockerDeploy.getContainerName()+"】" + "【"+dockerDeploy.getContainerID()+"】";
                CornJonEntity cornJonEntity = new CornJonEntity(dockerDeploy.getId(),
                        aliseName,IntervalBackupContainerVolume.class, dockerDeploy,dockerDeploy.getScheduledCorn());
                cornJonEntity.start();
            }
            return ResultVO.success();
        }catch (Exception e){
            e.printStackTrace();
        }
        return ResultVO.failed();
    }

    @RequestMapping("/getBackupList")
    public ResultVO getBackupList(@NestingModel DockerDeploy model){
        try{
            String command = "ls  /data/volume_backup/"+model.getContainerID()+"/ | awk '{print}' ";
            ResultVO resultVO = RemoteExecute.executeSsh(command);
            return resultVO;
        }catch (Exception e){
            e.printStackTrace();
        }
        return ResultVO.failed();
    }

    @RequestMapping("/restoreContainerData")
    public ResultVO restoreContainerData(String name,String id){
        try {
            DockerDeploy dockerDeploy = dockerDeployService.getDockerDeployById(id);
            List<DockerDeployVolume> list  = dockerDeployService.getDockerDeployVolumeList(id);
            StringBuffer stringBuffer = new StringBuffer();
            for(DockerDeployVolume dockerDeployVolume : list){
                stringBuffer.append(dockerDeployVolume.getHostPath()).append(" ");
            }
            String saveDockerContainerVolumePath = DataTools.getSystemSettingStringValByKey("docker.container.volume.backup.path");
            String command = "docker stop " + dockerDeploy.getContainerID();
            String command2 = "rm -rf " + stringBuffer.toString();
            String command3 = "tar -xvzf " + saveDockerContainerVolumePath + "/" + dockerDeploy.getContainerID() + "/" + name + " -C /";
            String command4 = "docker start " + dockerDeploy.getContainerID();
            ResultVO resultVO = RemoteExecute.executeSsh(command,command2,command3,command4);
            return resultVO;
        }catch (Exception e){
            e.printStackTrace();
        }
        return ResultVO.failed();
    }

    @RequestMapping("/clearExceptionContainers")
    public ResultVO clearExceptionContainers(String containerIds){
        try{
            List<DockerDeploy> list = dockerDeployService.getDockerDeployByIds(containerIds);
            String url = DataTools.getSystemSettingStringValByKey("issue_instructions_url");
            if(list == null || list.size() == 0){
                return ResultVO.failed("没有查询到可用容器!");
            }
            JSONObject params = new JSONObject();
            JSONArray containers = new JSONArray();
            String serialNumber = DataTools.getSerialNumber();
            params.put("serialNumber", serialNumber);
            for(DockerDeploy dockerDeploy : list){
                JSONObject container = new JSONObject();
                container.put("containerId",dockerDeploy.getContainerID());
                container.put("filePath","/data/data/1.tar.gz");
                containers.add(container);
            }
            params.put("containers",containers);
            JSONObject request = new JSONObject();
            request.put("code", TcpDataType.EXCEPTION_CONTAINER_REPORT.getCode());
            request.put("content",params);

            ResultVO resultVO = RemoteExecute.executeTcpInstruction(url, request.toString());
            DataTools.putWebSessionId(serialNumber);

            return resultVO;
        }catch (Exception e){
            e.printStackTrace();
        }
        return ResultVO.failed();
    }

}
